<template>
    <div>
        <!-- 三级分类下拉框 -->
        <el-card style="margin: 20px 0px">
            <!-- 绑定自定义事件，用于接收子组件传过来的三个商品id  用props给父组件传递数据 -->
            <CategorySelect @getCategoryId="getCategoryId" :show="!isShowTable"/>
        </el-card>
        <!-- 三级分类数据表格 -->
        <el-card>
            <div v-show="isShowTable">
                <!-- disabled.没有category3Id的时候，category3Id为空，隐式转换为false，加非! ,转化为 true -->
                <el-button type="primary" icon="el-icon-plus" style="margin-bottom: 10px" :disabled="!category3Id"
                           @click="addAttr">添加属性
                </el-button>
                <!-- 表格 : 展示平台属性数据 -->
                <el-table :data="attrList" style="width: 100%" border>
                    <el-table-column label="序号" width="80" type="index" align="center">
                    </el-table-column>

                    <el-table-column prop="attrName" label="属性名称" width="180">
                    </el-table-column>

                    <el-table-column prop="attrValueList.valueName" label="属性值列表">
                        <template slot-scope="{row,$index}">
                            <el-tag type="success" v-for="(attrValue,index) in row.attrValueList" :key="attrValue.id"
                                    style="margin: 0 10px">
                                {{ attrValue.valueName }}
                            </el-tag>
                        </template>
                    </el-table-column>

                    <el-table-column prop="address" label="操作" width="180">
                        <template slot-scope="{row,$index}">
                            <el-button type="warning" icon="el-icon-edit" size="mini" @click="updateAttr(row)">修改</el-button>
                            <el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </div>
            <!-- 添加或修改属性的结构 -->
            <div v-show="!isShowTable">
                <el-form :inline="true" class="demo-form-inline" :model="attrInfo">
                    <el-form-item label="属性名">
                        <el-input placeholder="请输入属性名" v-model="attrInfo.attrName"></el-input>
                    </el-form-item>
                </el-form>
                <!-- 属性名为空的时候，添加属性值按钮不可点击 ，非空才可点击 -->
                <el-button type="primary" icon="el-icon-plus" @click="addAttrValue" :disabled="!attrInfo.attrName">添加属性值</el-button>
                <el-button @click="cancel">取消</el-button>
                <el-table  style="width: 100%;margin: 20px 0" border :data="attrInfo.attrValueList">
                    <el-table-column type="index" label="序号" width="80" align="center">
                    </el-table-column>

                    <el-table-column prop="name" label="属性值名称">
                        <template slot-scope="{row,$index}">
                            <el-input
                                v-model="row.valueName"
                                placeholder="请输入属性值名称"
                                size="mini" v-if="row.flag"
                                @blur="toLook(row)"
                                @keyup.native.enter="toLook(row)"
                                :ref="$index"
                            ></el-input>
                            <span v-else style="display: block" @dblclick="toEdit(row,$index)" @blur="toLook(row)"  >
                                {{row.valueName}}
                            </span>
                        </template>
                    </el-table-column>

                    <el-table-column prop="address" label="操作" width="180">
                        <template slot-scope="{row,$index}">
                            <!-- 气泡确认框   点击确定，触发 @confirm中的回调函数 -->
                            <el-popconfirm :title='`确定删除"${row.valueName}"吗？`' @onConfirm="deleteAttrValue($index)">
                            <el-button
                                type="danger"
                                icon="el-icon-delete"
                                size="mini"
                                slot="reference">删除</el-button>
                            </el-popconfirm>
                        </template>
                    </el-table-column>
                </el-table>
                <!-- 没有属性值的时候，保存按钮不可点击 -->
                <el-button type="primary" @click="addOrUpdateAttr" :disabled="attrInfo.attrValueList.length<1">保存</el-button>
                <el-button @click="cancel">取消</el-button>
            </div>
        </el-card>
    </div>
</template>

<script>
// 按需引入lodash
import cloneDeep from 'lodash/cloneDeep'
export default {
    name: "Attr",
    data() {
        return {
            // 一级分类、二级分类、三级分类的id
            category1Id: '',
            category2Id: '',
            category3Id: '',
            // 存储服务器返回的数据
            attrList: [],
            // 控制三级分类数据表格是否显示，默认为true，点击添加属性变为false
            isShowTable:true,
            // 收集新增属性或修改属性
            attrInfo:{
                attrName:'',                // 属性名
                attrValueList:[             // 属性名中的属性值，因为属性值可以是多个，因此需要的是数组
                    /*{                       // 每一个属性值都是一个对象，需要attrId、valueName
                        attrId:0,           // 属性名的id
                        valueName:''    // 属性值
                    }*/
                ],
                categoryId:0,               // 就是 category3Id
                categoryLevel:3             // 就是 3，因为服务器也需要区分是几级分类
            }
        }
    },
    methods: {
        // 用于接收子组件传过来的三个商品id
        getCategoryId({categoryId, level}) {
            // console.log(categoryId,level)
            // 区分 三级分类 相应的id，以及父组件进行存储
            if (level == 1) {
                this.category1Id = categoryId
                // 一级分类的商品id发生变化时，清空二级和三级分类的id
                this.category2Id = ''
                this.category3Id = ''
            } else if (level == 2) {
                this.category2Id = categoryId
                // 二级分类的商品id发生变化时，清空三级分类的id
                this.category3Id = ''
            } else {
                // 走到这里，代表三个级别分类里面都有数据了，就可以发请求了
                this.category3Id = categoryId
                // 发请求      // 先放着，回头在写
                this.getAttrList()
            }
        },
        // 获取平台属性的数据    当用户确定三级分类的时候，可以向服务器发请求获取平台属性进行展示
        async getAttrList() {
            // 解构
            const {category1Id, category2Id, category3Id} = this
            let aResult = await this.$API.attr.reqAttrList(category1Id, category2Id, category3Id)
            // console.log(aResult)
            if (aResult.code == 200) {
                this.attrList = aResult.data
            }
        },
        // 点击添加属性值
        async addAttrValue() {
            // 向attrValueList属性值中添加元素，初始的时候属性值里面没有内容。点击之后才会有，页面才会出现
            // attrId:是相应的属性的id，目前而言是添加属性的操作，还没有相应的属性的id，所以带给服务器的id先为undefined
            this.attrInfo.attrValueList.push({
                // 修改某一个属性的，可以在已有的属性值基础之上新增新的属性值，新增属性值的时候，需要把已有的属性的id带过去
                attrId:this.attrInfo.id,
                valueName:'',
                // 标识符，用于控制编辑模式与查看模式的切换
                flag:true
            })
            this.$nextTick(() => {
                // 要给数组的最后一个添加添加获取焦点
                this.$refs[this.attrInfo.attrValueList.length - 1].focus()
            })
        },
        // 取消按钮
        cancel() {
            // 显示添加属性表格
            this.isShowTable = true
            // 点完取消，再点添加属性会把之前留下的数据再次显示出来，就是数据回显问题
            // attrInfo.attrName 置空
        },
        // 点击【添加属性】
        addAttr() {
            // / 隐藏表格
            this.isShowTable = false
            // 点完取消，再点添加属性会把之前留下的数据再次显示出来，就是数据回显问题
            // 点击完，可以取到三级分类的id
            this.attrInfo = {
                attrName:'',                // 属性名
                attrValueList:[],            // 属性名中的属性值，因为属性值可以是多个，因此需要的是数组
                categoryId:this.category3Id,               // 就是 category3Id
                categoryLevel:3             // 就是 3，因为服务器也需要区分是几级分类
            }
        },
        // 修改属性
        updateAttr(row) {
            // console.log(row)
            // 隐藏添加属性表格
            this.isShowTable = false
            // 将传过来的row赋值给attrinfo
            // this.attrInfo = row 这样写会有一个问题，就是当修改完，又不想修改了，点击了取消，但是数据依然发生了变化。
            // 由于数据结构中存在对象里面套数组，数组里面套对象。解决这样的问题用深拷贝，可使用插件 lodash
            this.attrInfo = cloneDeep(row)
            // 遍历数组，给每一个元素添加一个属性为 flag，值默认为false
            this.attrInfo.attrValueList.forEach(item => {
                // 此处需要用到$set,响应式数据
                // $set 第一个参数：对象，给谁身上加； 第二个参数：要增加的属性；   第三个属性：新增的属性的属性值
                this.$set(item,'flag',false)
            })
        },
        // 失去焦点事件和键盘敲击entry事件,输入框切换为span，编辑模式切换为查看模式
        toLook(row) {
            // row 是当前用户添加的最新的属性值
            // 如果属性值为空，不能作为新的属性值添加进去，需要给用户提示，让用户输入一个其他的属性值
            if (row.valueName.trim()=='') {
                this.$message.warning( '请输入一个正常的属性值')
                return;
            }
            // 新增的属性值不能与已有的属性值重复
            let resultt = this.attrInfo.attrValueList.some(item => {
                // 需要将 row从数组里面判断中去除，row是最新新增的属性值【数组的最后一项元素】
                if (row!==item) {
                    return row.valueName == item.valueName
                }
            })
            // 如果有重复的内容，就返回true
            // console.log(resultt)
            if (resultt) {
                this.$message.warning('请不要输入重复的属性值')
                return;
            }
            // 将当前编辑模式转为查看模式，input消失，显示span
            row.flag = false
        },
        // 鼠标双击事件，查看模式切换为编辑模式
        toEdit(row,index) {
            row.flag = true
            this.$nextTick( () =>{
                this.$refs[index].focus()
            })
        },
        // 气泡确认框确定按钮的回调，删除属性值的操作(添加或者修改属性值的时候)
        // 此项目用的elementUI版本不是最新版，确定按钮的回调用这个 @onConfirm
        deleteAttrValue(index) {
            // 当前删除属性值的操作是不需要发请求的
            this.attrInfo.attrValueList.splice(index,1)
        },
        // 保存或修改属性、属性值
        async addOrUpdateAttr() {
            // 整理参数，1.属性值如果为空，不应该提交
            //         2. 参数中不应该有flag字段（因为是后续自己加上的，发请求的时候要去掉）
            // 点击保存，向服务器发请求
            this.attrInfo.attrValueList = this.attrInfo.attrValueList.filter((item) => {
                // console.log(item)
                // 过滤出来属性值不是空的
                if (item.valueName != '') {
                    delete item.flag
                    return true
                }
            })
            try {
                await this.$API.attr.reqAddOrUpdateAttr(this.attrInfo)
                this.$message.success('保存成功！')
                // 重新获取页面数据
                this.getAttrList()
                // 页面跳转
                this.isShowTable = true
            } catch (error) {
                this.$message.error('保存失败')
            }
            /*let aRusult = await this.$API.attr.reqAddOrUpdateAttr(this.attrInfo)
            // console.log(aRusult)
            // 保存或修改成功
            if (aRusult.code == 200) {
                this.$message.success('保存成功！')
                // 重新获取页面数据
                this.getAttrList()
                // 页面跳转
                this.isShowTable = true
            } else {
                this.$message.error('保存失败')
            }*/
        }
    }
}
</script>

<style scoped>

</style>
